package com.nekonomics
package types

import doobie.Meta
import zio.json.JsonEncoder


opaque type Money = BigDecimal

object Money {

  given Ordering[Money] = Ordering.by(_.value)
  given Meta[Money] = Meta[BigDecimal].timap(Money.apply)(_.value)
  given JsonEncoder[Money] = JsonEncoder[String].contramap(_.value.toString)
  
  private val scale: Int = 2

  // todo 考虑四舍五入

  //  private val roundingMode: JRoundingMode = JRoundingMode.HALF_UP

  def apply(bd: BigDecimal): Money =
    bd.setScale(scale)

  def fromDouble(d: Double): Money =
    apply(BigDecimal(d))

  def fromString(s: String): Option[Money] =
    scala.util.Try(BigDecimal(s)).toOption.map(apply)

  val zero: Money = apply(BigDecimal(0))

  extension (m: Money) {
    def value: BigDecimal = m

    def +(other: Money): Money = apply(m + other)
    def -(other: Money): Money = apply(m - other)
    def *(n: BigDecimal): Money = apply(m * n)
    def /(n: BigDecimal): Money = apply(m / n)

    def toBigDecimal: BigDecimal = m
    def toDouble: Double = m.toDouble
    def toString: String = m.setScale(scale).toString
    def toStringWithSymbol(symbol: String = "¥"): String =
      s"$symbol${m.setScale(scale)}"


  }
}